package me.jessyan.retrofiturlmanager;

import io.reactivex.ObservableTransformer;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import me.jessyan.retrofiturlmanager.demo.NetWorkManager;
import me.jessyan.retrofiturlmanager.manager.RetrofitUrlManager;
import okhttp3.HttpUrl;
import okhttp3.ResponseBody;
import org.junit.Test;

import java.util.Objects;

import static org.junit.Assert.*;

public class UrlManagerTest {

    private static String url;

    private static final int TEN = 10;

    private static final int ONE_TWO_TWO = 1220562;

    @Test
    public void startAdvancedModelTest() {
        url = "http://jessyan.me/1";
        String getBaseUrl;
        int num = RetrofitUrlManager.getInstance().getPathSize();

        assertEquals(0, num);

        RetrofitUrlManager.getInstance().startAdvancedModel(url);
        getBaseUrl = RetrofitUrlManager.getInstance().getBaseUrl().encodedPath();

        assertEquals("/1", getBaseUrl);

        num = RetrofitUrlManager.getInstance().getPathSize();

        assertEquals(1, num);

        // change url
        url = "http://jessyan.me/1/new-1/new-2";
        RetrofitUrlManager.getInstance().startAdvancedModel(url);
        num = RetrofitUrlManager.getInstance().getPathSize();

        assertEquals(3, num);

        getBaseUrl = RetrofitUrlManager.getInstance().getBaseUrl().encodedPath();

        assertEquals("/1/new-1/new-2", getBaseUrl);
    }

    @Test
    public void setUrlNotChangeTest() {
        String getUrl = RetrofitUrlManager.getInstance().setUrlNotChange(url);
        assertTrue(getUrl.endsWith("#url_ignore"));
    }

    @Test
    public void btnRequestDefaultTest() {
        NetWorkManager
                .getInstance()
                .getOneApiService()
                .requestDefault()
                .compose(getDefaultTransformer())
                .subscribe(getDefaultObserver());
    }

    @Test
    public void btnRequestDefaultToComposeTest() {
        NetWorkManager
                .getInstance()
                .getOneApiService()
                .requestDefault()
                .compose(getDefaultTransformer());
    }

    @Test
    public void btnRequestDefaultToSubscribeTest() {
        NetWorkManager
                .getInstance()
                .getOneApiService()
                .requestDefault()
                .subscribe(getDefaultObserver());
    }

    @Test
    public void btnSetGlobalUrlTest() {
        url = "http://www.baidu.com/";
        RetrofitUrlManager.getInstance().setGlobalDomain(url);
        HttpUrl httpUrl = RetrofitUrlManager.getInstance().getGlobalDomain();

        assertEquals(url, httpUrl.toString());
    }

    @Test
    public void btnRemoveGlobalUrlTest() {
        url = "http://www.baidu.com/";
        RetrofitUrlManager.getInstance().setGlobalDomain(url);
        HttpUrl httpUrl = RetrofitUrlManager.getInstance().getGlobalDomain();

        assertEquals(url, httpUrl.toString());

        RetrofitUrlManager.getInstance().removeGlobalDomain();
        httpUrl = RetrofitUrlManager.getInstance().getGlobalDomain();

        assertNull(httpUrl);
    }

    @Test
    public void getUsersTest() {
        NetWorkManager
                .getInstance()
                .getOneApiService()
                .getUsers(1, TEN)
                .compose(getDefaultTransformer())
                .subscribe(getDefaultObserver());
    }

    @Test
    public void getDataTest() {
        NetWorkManager
                .getInstance()
                .getTwoApiService()
                .getData(TEN, 1)
                .compose(getDefaultTransformer())
                .subscribe(getDefaultObserver());
    }

    @Test
    public void getBookTest() {
        NetWorkManager
                .getInstance()
                .getThreeApiService()
                .getBook(ONE_TWO_TWO)
                .compose(getDefaultTransformer())
                .subscribe(getDefaultObserver());

    }

    private <T> ObservableTransformer<T, T> getDefaultTransformer() {
        return upstream -> {
            assertNotNull(upstream);
            return upstream.subscribeOn(Schedulers.io()).doOnSubscribe(disposable -> assertFalse(disposable.isDisposed()));
        };
    }

    private Observer<ResponseBody> getDefaultObserver() {
        return new Observer<ResponseBody>() {
            @Override
            public void onSubscribe(Disposable d) {
                assertFalse(d.isDisposed());
                // d.dispose(); // d.dispose 设置 isDisposed 为 True
                // assertTrue(d.isDisposed());
            }

            @Override
            public void onNext(ResponseBody response) {
                try {
                    assertEquals("text/html; charset=utf-8", Objects.requireNonNull(response.contentType()).toString());
                } catch (Exception e) { fail(); }
            }

            @Override
            public void onError(Throwable throwable) { fail(); }
            @Override
            public void onComplete() { }
        };
    }
}